mysql Innodb索引

基本概念

  对于mysql目前的默认存储引擎Innodb来说,索引分为2个,一个是聚集索引,一个是普通索引(也叫二级索引)。
  聚集索引:聚集索引的顺序和数据在磁盘的顺序一致,因此查询时使用聚集索引,效率更高,但是因此聚集索引也只能一条。一般来说,主键就是聚集索引,当然没有主键的话,就会创建一个隐藏的列来作为聚集索引列。B+树的叶子节点就是数据值
  2级索引就是不是聚集索引的索引了。其叶子节点存的是指向数据值的地址。

为什么需要索引?

  数据存储到数据库中是以数据块作为基本单位存放的,每个表有个参数叫块因子,就是一个数据块能存多少行记录,这个和你设置的数据块大小以及表的设计相关。
  如果对一个无序字段进行搜索,那么就只能使用线性搜索。时间复杂度为n/2,如果是一个有序字段那么可以使用2分查找法,时间复杂度为log2 (N)。
  如果对关键字段建立了索引,那么就会对这个关键字生成索引文件,也是以数据块作为单位存储的。第一这个数据是有序的,第二他的块因子很大,为什么呢?因为他只是一列或者几列数据,不是整列数据。
  举个例子:
  前置条件:数据块默认大小:1024字节,表行长度500字节,某索引字节5字节。数据5000000条。
  1:无索引:查找字段无序:1024/500=2, 5000000/2=2500000块数据块,线性搜索:查找1250000次。
  2:无索引:查找字段有序, 1024/500=2,5000000/2=2500000块数据块,有序,使用2分查找。Log2(2500000)=752 575

  3:有索引:1024/5=204, 5000000/204=24509块数据块,有序,使用2分查找。Log2(24509)=7378。
  数量级:百万,十万,千。在这里,我只是用2分查找来代替引用,只是为了形成一个对比。索引不是链表是B+树(Innodb)

为何索引是B+树?

  一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。
  因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。
  预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。
  数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。
  相对高瘦平衡二叉树,b+树就显得很矮胖,故查询次数也就更低一些,上面说的节点,就是索引。B树已经很不错了,为何会是b+树,他们2个怎么说呢,b树的节点利用率更加高,每一个节点都是存放了数据,而B+树则是只有叶子节点存放了数据,并且相邻叶子节点之间有个链接,作为一个小链表结构,那么这同时意味着非叶子几点几乎都没有使用,造成了浪费,但是对于数据库来说,我们很多查询都是范围查询,如果有了链表那么就不用再去父节点重新查询新数据了,更加适合于数据库的使用